using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Admin.NET.Application.Entity.Business;
using Admin.NET.Application.EventBus;
using Admin.NET.Application.Mqtt.mqttresponse;
using Admin.NET.Application.Service.Electricity.Dto;
using Admin.NET.Core;
using Admin.NET.Core.Service;
using Furion;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.EventBus;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using SqlSugar;
using Yitter.IdGenerator;

namespace Admin.NET.Application.Service.Electricity;

[ApiDescriptionSettings(new string[] { "业务应用" }, Order = 100)]
public class EPowerService : IDynamicApiController, ITransient, IPrivateDependency
{
	/// <summary>
	/// 设备离线
	/// </summary>
	/// <param name="sn">序列号</param>
	/// <param name="type">类型，0电表，1网关</param>
	/// <returns></returns>
	public async Task MeterOffline(string sn, int type)
	{
		switch (type)
		{
		case 0:
		{
			SqlSugarRepository<ElectricMeter> _contextold = App.GetService<SqlSugarRepository<ElectricMeter>>();
			SimpleClient<ElectricMeter> _context = _contextold.CopyNew();
			ElectricMeter meter = await (from u in _context.Context.Queryable<ElectricMeter>()
				where u.Sn == sn && u.ProtocolType == 0
				select u).FirstAsync();
			if (meter != null)
			{
				meter.SignalStatus = 0;
				meter.LastOnlineTime = DateTime.Now;
				DateTime dateTime = DateTime.Now;
				EarlyWarning earlyWarning = new EarlyWarning
				{
					TenantId = meter.TenantId,
					CreateTime = dateTime,
					Status = 0,
					IsDelete = false,
					WarningId = meter.Id,
					WarningTarget = meter.Sn,
					WarningTargetType = 1,
					WarningType = 1,
					WarningMsg = $"当前电表{meter.Name}，设备编号{meter.Sn}已离线"
				};
				await _context.Context.Updateable(meter).UpdateColumns((ElectricMeter u) => new { u.SignalStatus, u.LastOnlineTime }).ExecuteCommandAsync();
				await _context.Context.Insertable(earlyWarning).ExecuteCommandAsync();
			}
			break;
		}
		case 1:
		{
			SqlSugarRepository<Admin.NET.Application.Collector> _contextold = App.GetService<SqlSugarRepository<Admin.NET.Application.Collector>>();
			SimpleClient<Admin.NET.Application.Collector> _context = _contextold.CopyNew();
			Admin.NET.Application.Collector collectors = await (from u in _context.Context.Queryable<Admin.NET.Application.Collector>()
				where u.Imei == sn
				select u).FirstAsync();
			if (collectors != null)
			{
				collectors.Status = 0;
				collectors.LastOnlineTime = DateTime.Now;
				DateTime dateTime = DateTime.Now;
				EarlyWarning earlyWarning = new EarlyWarning
				{
					TenantId = collectors.TenantId,
					CreateTime = dateTime,
					Status = 0,
					IsDelete = false,
					WarningId = collectors.Id,
					WarningTarget = collectors.Imei,
					WarningTargetType = 1,
					WarningType = 1,
					WarningMsg = $"当前采集器{collectors.Name}，设备编号{collectors.Imei}已离线"
				};
				await _context.Context.Updateable(collectors).UpdateColumns((Admin.NET.Application.Collector u) => new { u.Status, u.LastOnlineTime }).ExecuteCommandAsync();
				await (from u in _context.Context.Updateable<ElectricMeter>()
					where u.CollectorId == (long?)collectors.Id
					select u).SetColumns((ElectricMeter u) => u.SignalStatus == 0).SetColumns((ElectricMeter u) => u.LastOnlineTime == DateTime.Now).ExecuteCommandAsync();
				await _context.Context.Insertable(earlyWarning).ExecuteCommandAsync();
			}
			break;
		}
		}
	}

	/// <summary>
	/// 设备在线
	/// </summary>
	/// <param name="sn">序列号</param>
	/// <param name="type">类型，0电表，1网关</param>
	/// <param name="upload">上报的数据</param>
	/// <param name="rssi">信号强度</param>
	/// <returns></returns>
	public async Task MeterOnline(string sn, int type, UploadFirstDto upload, int? rssi)
	{
		switch (type)
		{
		case 0:
		{
			SqlSugarRepository<ElectricMeter> _contextold = App.GetService<SqlSugarRepository<ElectricMeter>>();
			SimpleClient<ElectricMeter> _context = _contextold.CopyNew();
			ElectricMeter meter = await (from u in _context.Context.Queryable<ElectricMeter>()
				where u.Sn == sn
				select u).FirstAsync();
			if (meter != null)
			{
				meter.SignalStatus = 1;
				meter.LastOnlineTime = DateTime.Now;
				meter.Latitude = upload.lat;
				meter.Longitude = upload.lng;
				meter.RSSI = rssi;
				await _context.Context.Updateable(meter).UpdateColumns((ElectricMeter u) => new { u.SignalStatus, u.LastOnlineTime, u.Latitude, u.Longitude, u.RSSI }).ExecuteCommandAsync();
			}
			break;
		}
		case 1:
		{
			SqlSugarRepository<Admin.NET.Application.Collector> _contextold = App.GetService<SqlSugarRepository<Admin.NET.Application.Collector>>();
			SimpleClient<Admin.NET.Application.Collector> _context = _contextold.CopyNew();
			Admin.NET.Application.Collector collectors = await (from u in _context.Context.Queryable<Admin.NET.Application.Collector>()
				where u.Imei == sn
				select u).FirstAsync();
			if (collectors == null)
			{
				break;
			}
			collectors.Status = 1;
			collectors.LastOnlineTime = DateTime.Now;
			collectors.Latitude = upload.lat;
			collectors.Longitude = upload.lng;
			collectors.RSSI = rssi;
			await _context.Context.Updateable(collectors).UpdateColumns((Admin.NET.Application.Collector u) => new { u.Status, u.LastOnlineTime, u.Latitude, u.Longitude, u.RSSI }).ExecuteCommandAsync();
			if (upload.device != null && upload.device.Count() > 0)
			{
				await (from u in _context.Context.Updateable<ElectricMeter>()
					where u.CollectorId == (long?)collectors.Id && upload.device.Contains<string>(u.LowAddr)
					select u).SetColumns((ElectricMeter u) => u.Latitude == (decimal?)upload.lat).SetColumns((ElectricMeter u) => u.Longitude == (decimal?)upload.lng).ExecuteCommandAsync();
			}
			break;
		}
		}
	}

	/// <summary>
	/// 设备预警，不一定通用
	/// </summary>
	/// <param name="sn">序列号</param>
	/// <param name="type">0电表，1网关</param>
	/// <param name="upload"></param>
	/// <returns></returns>
	public async Task MeterAlarm(string sn, int type, UploadAlarm upload)
	{
		SqlSugarRepository<EarlyWarning> _contextold = App.GetService<SqlSugarRepository<EarlyWarning>>();
		SimpleClient<EarlyWarning> _context = _contextold.CopyNew();
		switch (type)
		{
		case 0:
		{
			ElectricMeter meter = await (from u in _context.Context.Queryable<ElectricMeter>()
				where u.Sn == sn
				select u).FirstAsync();
			DateTime dateTime = DateTime.Now;
			if (meter != null)
			{
				EarlyWarning earlyWarning = new EarlyWarning
				{
					TenantId = meter.TenantId,
					CreateTime = dateTime,
					Status = 0,
					IsDelete = false,
					WarningId = meter.Id,
					WarningTarget = meter.Sn,
					WarningTargetType = 0,
					WarningType = 0
				};
				earlyWarning.WarningMsg = $"当前电表{meter.Name}，设备编号{meter.Sn}已断电";
				meter.GateStatus = 0;
				await _context.Context.Updateable(meter).UpdateColumns((ElectricMeter u) => new { u.GateStatus }).ExecuteCommandAsync();
				await _context.Context.Insertable(earlyWarning).ExecuteCommandAsync();
			}
			break;
		}
		case 1:
		{
			Admin.NET.Application.Collector collectors = await (from u in _context.Context.Queryable<Admin.NET.Application.Collector>()
				where u.Imei == sn
				select u).FirstAsync();
			DateTime dateTime = DateTime.Now;
			if (collectors == null)
			{
				break;
			}
			EarlyWarning earlyWarning = new EarlyWarning
			{
				TenantId = collectors.TenantId,
				CreateTime = dateTime,
				Status = 0,
				IsDelete = false,
				WarningId = collectors.Id,
				WarningTarget = collectors.Imei,
				WarningTargetType = 1,
				WarningType = 0
			};
			ElectricMeter meterInfo = await (from u in _context.Context.Queryable<ElectricMeter>()
				where u.LowAddr == upload.Device && u.CollectorId == (long?)collectors.Id
				select u).FirstAsync();
			if (meterInfo != null)
			{
				earlyWarning.WarningId = meterInfo.Id;
				earlyWarning.WarningTarget = meterInfo.Sn;
				earlyWarning.WarningMsg = $"当前电表{meterInfo.Name}，编号{meterInfo.Sn}已断电";
				earlyWarning.WarningTargetType = 0;
				meterInfo.GateStatus = 0;
				await _context.Context.Updateable(meterInfo).UpdateColumns((ElectricMeter u) => new { u.GateStatus }).ExecuteCommandAsync();
			}
			else
			{
				earlyWarning.WarningMsg = $"当前采集网关{collectors.Name}，编号{collectors.Imei}下属电表编号{upload.Device}已断电，但在系统无存档";
			}
			await _context.Context.Insertable(earlyWarning).ExecuteCommandAsync();
			break;
		}
		}
	}

	public async Task MeterUpload(string sn, int type, Dictionary<string, UploadMqttInfo> info)
	{
		string deviceKey = "";
		if (info != null && info.Count > 0)
		{
			deviceKey = info.Keys.First();
		}
		PowerConsumptionRecord powerConsumption = null;
		SqlSugarRepository<ElectricMeter> _contextold = App.GetService<SqlSugarRepository<ElectricMeter>>();
		SimpleClient<ElectricMeter> _context = _contextold.CopyNew();
		SqlSugarRepository<PowerConsumptionRecord> _contextTwoold = App.GetService<SqlSugarRepository<PowerConsumptionRecord>>();
		SimpleClient<PowerConsumptionRecord> _contextTwo = _contextTwoold.CopyNew();
		ElectricMeter meterInfo = null;
		bool isSwitch = false;
		if (_context == null)
		{
			return;
		}
		try
		{
			try
			{
				_context.Context.CurrentConnectionConfig.IsAutoCloseConnection = false;
				_contextTwo.Context.CurrentConnectionConfig.IsAutoCloseConnection = false;
				await _context.Context.Ado.BeginTranAsync();
				await _contextTwo.Context.Ado.BeginTranAsync();
				Admin.NET.Application.Collector collector = null;
				switch (type)
				{
				case 0:
				{
					ElectricMeter electricMeter2 = await (from u in _context.Context.Queryable<ElectricMeter>()
						where u.IsDelete == false && u.Sn == sn
						select u).FirstAsync();
					meterInfo = electricMeter2;
					break;
				}
				case 1:
				{
					collector = await (from u in _context.Context.Queryable<Admin.NET.Application.Collector>()
						where u.Imei == sn
						select u).FirstAsync();
					if (collector == null)
					{
						return;
					}
					ElectricMeter electricMeter = await (from u in _context.Context.Queryable<ElectricMeter>()
						where u.IsDelete == false
						select u).WhereIF(collector != null, (ElectricMeter u) => u.LowAddr == deviceKey && u.CollectorId == (long?)collector.Id).FirstAsync();
					meterInfo = electricMeter;
					break;
				}
				}
				UploadMqttInfo upload;
				Room roomInfo;
				ElectricityPriceRule ruleInfo;
				string[] total;
				if (meterInfo != null)
				{
					upload = info[deviceKey];
					await FreezeInfoHandle(_contextold, meterInfo, upload.Time, upload.AllTotalFreeze);
					if (!string.IsNullOrEmpty(upload.State))
					{
						meterInfo.GateStatus = ((upload.State == "0000") ? 1 : 0);
					}
					meterInfo.SignalStatus = 1;
					if (upload.State == "" && upload.Alltotal == "")
					{
						if (string.IsNullOrEmpty(upload.TotalE))
						{
							meterInfo.SignalStatus = 0;
						}
						if (collector != null)
						{
							collector.Status = 1;
							collector.LastOnlineTime = DateTime.Now;
							_context.Context.Updateable(collector).UpdateColumns((Admin.NET.Application.Collector u) => new { u.Status, u.LastOnlineTime }).ExecuteCommand();
						}
						_context.Context.Updateable(meterInfo).UpdateColumns((ElectricMeter u) => new { u.SignalStatus, u.GateStatus }).ExecuteCommand();
						await _context.Context.Ado.CommitTranAsync();
						await _contextTwo.Context.Ado.CommitTranAsync();
						return;
					}
					meterInfo.LatestMeterReadingTime = DateTime.Now;
					roomInfo = null;
					if (meterInfo.RoomId.HasValue)
					{
						roomInfo = await (from u in _context.Context.Queryable<Room>()
							where (long?)u.Id == meterInfo.RoomId
							select u).FirstAsync();
					}
					ruleInfo = null;
					if (meterInfo.PriceRuleId.HasValue)
					{
						ruleInfo = await (from u in _context.Context.Queryable<ElectricityPriceRule>()
							where (long?)u.Id == meterInfo.PriceRuleId
							select u).FirstAsync();
					}
					total = upload.Alltotal?.Split(',') ?? new string[0];
					if (total.Length >= 5)
					{
						goto IL_1270;
					}
					if (string.IsNullOrWhiteSpace(upload.TotalE))
					{
						if (collector != null)
						{
							collector.Status = 1;
							collector.LastOnlineTime = DateTime.Now;
							_context.Context.Updateable(collector).UpdateColumns((Admin.NET.Application.Collector u) => new { u.Status, u.LastOnlineTime }).ExecuteCommand();
						}
						_context.Context.Updateable(meterInfo).UpdateColumns((ElectricMeter u) => new { u.SignalStatus, u.GateStatus, u.LatestMeterReadingTime }).ExecuteCommand();
						await _context.Context.Ado.CommitTranAsync();
						return;
					}
					total = new string[6] { "0", "0", "0", "0", "0", upload.TotalE };
					goto IL_1270;
				}
				if (collector != null)
				{
					collector.Status = 1;
					collector.LastOnlineTime = DateTime.Now;
					_context.Context.Updateable(collector).UpdateColumns((Admin.NET.Application.Collector u) => new { u.Status, u.LastOnlineTime }).ExecuteCommand();
				}
				goto IL_3c92;
				IL_362c:
				int num;
				decimal nowBalance;
				IUpdateable<Room> updateRoom;
				if (num != 0 && roomInfo.OwnerId.HasValue)
				{
					Owner owner = await (from u in _context.Context.Queryable<Owner>()
						where (long?)u.Id == roomInfo.OwnerId
						select u).FirstAsync();
					if (owner != null && !string.IsNullOrEmpty(owner.PhoneNumber))
					{
						decimal newBalance = Math.Round(nowBalance, 2);
						BillNoticePayload billNoticePayload = new BillNoticePayload
						{
							Body = $"您的房间：{roomInfo.Name}余额不足，剩余{newBalance}元，请及时充值。",
							Subject = "余额不足提醒",
							Remark = "若已充值，请忽略",
							Owners = new List<Owner> { owner },
							RoomId = roomInfo.Id,
							RoomName = roomInfo.Name,
							Balance = newBalance,
							Path = "/userPage/roomDetail/roomDetail?meterId=" + roomInfo.Id
						};
						EventPayload payload = new EventPayload
						{
							Data = JsonConvert.SerializeObject(billNoticePayload),
							TenantId = roomInfo.TenantId.Value
						};
						for (int i = 0; i < 4; i++)
						{
							MessageCenter.PublishAsync($"{i}:SendEarlyWarningNotice", payload).Wait();
						}
						updateRoom = updateRoom.SetColumns((Room u) => u.LatestWarningBalance == (decimal?)nowBalance);
					}
				}
				goto IL_3a05;
				IL_1270:
				if (total.Length != 6)
				{
					string[] totalALL = new string[6] { "0", null, null, null, null, null };
					for (int i = 0; i < total.Length; i++)
					{
						totalALL[i + 1] = total[i];
					}
					total = totalALL;
				}
				decimal multiplier = (decimal)meterInfo.Multiplier;
				upload.TotalE = total[^1];
				upload.SharpElectricE = total[^2];
				upload.PeakElectricE = total[^3];
				upload.FlatElectricE = total[^4];
				upload.ValleyElectricE = total[^5];
				upload.DeepValleyElectricE = total[^6];
				decimal all = ChangeDataToD(upload.TotalE) * multiplier;
				decimal sharpElectricE = ChangeDataToD(upload.SharpElectricE) * multiplier;
				decimal peakElectricE = ChangeDataToD(upload.PeakElectricE) * multiplier;
				decimal flatElectricE = ChangeDataToD(upload.FlatElectricE) * multiplier;
				decimal valleyElectricE = ChangeDataToD(upload.ValleyElectricE) * multiplier;
				decimal deepvalleyElectricE = ChangeDataToD(upload.DeepValleyElectricE) * multiplier;
				decimal value = all;
				decimal? combinedActiveTotalElectricEnergy = meterInfo.CombinedActiveTotalElectricEnergy;
				decimal totalcheck = ((decimal?)value - combinedActiveTotalElectricEnergy).GetValueOrDefault();
				value = sharpElectricE;
				combinedActiveTotalElectricEnergy = meterInfo.CombinedActiveSharpElectricEnergy;
				decimal sharpElectricEcheck = ((decimal?)value - combinedActiveTotalElectricEnergy).GetValueOrDefault();
				value = peakElectricE;
				combinedActiveTotalElectricEnergy = meterInfo.CombinedActivePeakElectricEnergy;
				decimal peakElectricEcheck = ((decimal?)value - combinedActiveTotalElectricEnergy).GetValueOrDefault();
				value = flatElectricE;
				combinedActiveTotalElectricEnergy = meterInfo.CombinedActiveFlatElectricEnergy;
				decimal flatElectricEcheck = ((decimal?)value - combinedActiveTotalElectricEnergy).GetValueOrDefault();
				value = valleyElectricE;
				combinedActiveTotalElectricEnergy = meterInfo.CombinedActiveValleyElectricEnergy;
				decimal valleyElectricEcheck = ((decimal?)value - combinedActiveTotalElectricEnergy).GetValueOrDefault();
				value = deepvalleyElectricE;
				combinedActiveTotalElectricEnergy = meterInfo.CombinedActiveDeepValleyElectricEnergy;
				decimal deepvalleyElectricEcheck = ((decimal?)value - combinedActiveTotalElectricEnergy).GetValueOrDefault();
				SysCacheService _cache = App.GetService<SysCacheService>();
				List<BrandModel> brandModels = _cache.Get<List<BrandModel>>("BrandModels");
				if (brandModels.Count > 0)
				{
					BrandModel currentModel = brandModels.Where((BrandModel w) => w.Id == meterInfo.BrandId).FirstOrDefault();
					if (currentModel != null && currentModel.UpperLimitOfBase > 0m)
					{
						int num2;
						if (!(all > currentModel.UpperLimitOfBase))
						{
							combinedActiveTotalElectricEnergy = meterInfo.CombinedActiveTotalElectricEnergy;
							value = currentModel.UpperLimitOfBase;
							num2 = (((combinedActiveTotalElectricEnergy.GetValueOrDefault() > value) & combinedActiveTotalElectricEnergy.HasValue) ? 1 : 0);
						}
						else
						{
							num2 = 1;
						}
						if (num2 == 0)
						{
							value = currentModel.UpperLimitOfBase;
							combinedActiveTotalElectricEnergy = meterInfo.CombinedActiveTotalElectricEnergy;
							decimal? diff = (decimal?)value - combinedActiveTotalElectricEnergy;
							combinedActiveTotalElectricEnergy = diff;
							value = 1000;
							if ((combinedActiveTotalElectricEnergy.GetValueOrDefault() < value) & combinedActiveTotalElectricEnergy.HasValue)
							{
								SysUser manager = await (from u in _context.Context.Queryable<SysUser>()
									where u.TenantId == meterInfo.TenantId
									select u).FirstAsync();
								if (manager != null && !string.IsNullOrEmpty(manager.Phone))
								{
									ManagerNoticePayload managerNoticePayload = new ManagerNoticePayload
									{
										Body = $"您的电表：{meterInfo.Name}({meterInfo.Sn})已接近电表计量上限，为保证数据精准，请及时登录系统对该电表进行抄表清零。",
										Subject = $"电表{meterInfo.Name}({meterInfo.Sn})已接近计量上限",
										Remark = "若已操作，请忽略。",
										Owners = new List<SysUser> { manager },
										RoomId = roomInfo.Id,
										RoomName = roomInfo.Name
									};
									EventPayload payload = new EventPayload
									{
										Data = JsonConvert.SerializeObject(managerNoticePayload),
										TenantId = roomInfo.TenantId.Value
									};
									for (int i = 10; i < 14; i++)
									{
										MessageCenter.PublishAsync($"{i}:SendNoticeToManager", payload).Wait();
									}
								}
							}
						}
					}
				}
				decimal allfee = default(decimal);
				decimal lossfee = default(decimal);
				if (ruleInfo != null)
				{
					if (ruleInfo.Type == 0)
					{
						value = totalcheck;
						combinedActiveTotalElectricEnergy = ruleInfo.Price;
						allfee = ((decimal?)value * combinedActiveTotalElectricEnergy).GetValueOrDefault();
					}
					else
					{
						decimal num3 = allfee;
						value = sharpElectricEcheck;
						combinedActiveTotalElectricEnergy = ruleInfo.SharpPrice;
						allfee = num3 + ((decimal?)value * combinedActiveTotalElectricEnergy).GetValueOrDefault();
						decimal num4 = allfee;
						value = peakElectricEcheck;
						combinedActiveTotalElectricEnergy = ruleInfo.PeakPrice;
						allfee = num4 + ((decimal?)value * combinedActiveTotalElectricEnergy).GetValueOrDefault();
						decimal num5 = allfee;
						value = flatElectricEcheck;
						combinedActiveTotalElectricEnergy = ruleInfo.FlatPrice;
						allfee = num5 + ((decimal?)value * combinedActiveTotalElectricEnergy).GetValueOrDefault();
						decimal num6 = allfee;
						value = valleyElectricEcheck;
						combinedActiveTotalElectricEnergy = ruleInfo.ValleyPrice;
						allfee = num6 + ((decimal?)value * combinedActiveTotalElectricEnergy).GetValueOrDefault();
						decimal num7 = allfee;
						value = deepvalleyElectricEcheck;
						combinedActiveTotalElectricEnergy = ruleInfo.DeepValleyPrice;
						allfee = num7 + ((decimal?)value * combinedActiveTotalElectricEnergy).GetValueOrDefault();
					}
					if (allfee < 0m)
					{
						allfee = default(decimal);
					}
					if (allfee > 0m && meterInfo.ElectricityLossPercentage.HasValue && meterInfo.ElectricityLossPercentage > 0.0)
					{
						lossfee = allfee * (decimal)meterInfo.ElectricityLossPercentage.Value / 100m;
					}
				}
				if (sharpElectricE > 0m)
				{
					meterInfo.CombinedActiveSharpElectricEnergy = sharpElectricE;
				}
				if (flatElectricE > 0m)
				{
					meterInfo.CombinedActiveFlatElectricEnergy = flatElectricE;
				}
				if (peakElectricE > 0m)
				{
					meterInfo.CombinedActivePeakElectricEnergy = peakElectricE;
				}
				meterInfo.CombinedActiveTotalElectricEnergy = all;
				if (valleyElectricE > 0m)
				{
					meterInfo.CombinedActiveValleyElectricEnergy = valleyElectricE;
				}
				if (deepvalleyElectricE > 0m)
				{
					meterInfo.CombinedActiveDeepValleyElectricEnergy = deepvalleyElectricE;
				}
				if (collector != null)
				{
					collector.Status = 1;
					collector.LastOnlineTime = DateTime.Now;
					_context.Context.Updateable(collector).UpdateColumns((Admin.NET.Application.Collector u) => new { u.Status, u.LastOnlineTime }).ExecuteCommand();
				}
				meterInfo.IsRead = true;
				_context.Context.Updateable(meterInfo).UpdateColumns((ElectricMeter u) => new { u.CombinedActiveSharpElectricEnergy, u.CombinedActiveFlatElectricEnergy, u.CombinedActivePeakElectricEnergy, u.CombinedActiveTotalElectricEnergy, u.CombinedActiveDeepValleyElectricEnergy, u.CombinedActiveValleyElectricEnergy, u.SignalStatus, u.GateStatus, u.LatestMeterReadingTime, u.IsRead }).ExecuteCommand();
				powerConsumption = meterInfo.Adapt<PowerConsumptionRecord>();
				if (flatElectricE > 0m)
				{
					powerConsumption.CombinedActiveFlatElectricEnergyDifference = ((flatElectricEcheck < 0m) ? 0m : flatElectricEcheck);
				}
				else
				{
					powerConsumption.CombinedActiveFlatElectricEnergy = 0m;
				}
				if (peakElectricE > 0m)
				{
					powerConsumption.CombinedActivePeakElectricEnergyDifference = ((peakElectricEcheck < 0m) ? 0m : peakElectricEcheck);
				}
				else
				{
					powerConsumption.CombinedActivePeakElectricEnergy = 0m;
				}
				if (sharpElectricE > 0m)
				{
					powerConsumption.CombinedActiveSharpElectricEnergyDifference = ((sharpElectricEcheck < 0m) ? 0m : sharpElectricEcheck);
				}
				else
				{
					powerConsumption.CombinedActiveSharpElectricEnergy = 0m;
				}
				if (valleyElectricE > 0m)
				{
					powerConsumption.CombinedActiveValleyElectricEnergyDifference = ((valleyElectricEcheck < 0m) ? 0m : valleyElectricEcheck);
				}
				else
				{
					powerConsumption.CombinedActiveValleyElectricEnergy = 0m;
				}
				if (deepvalleyElectricE > 0m)
				{
					powerConsumption.CombinedActiveDeepValleyElectricEnergyDifference = ((deepvalleyElectricE < 0m) ? 0m : deepvalleyElectricE);
				}
				else
				{
					powerConsumption.CombinedActiveDeepValleyElectricEnergy = default(decimal);
				}
				powerConsumption.CombinedActiveTotalElectricEnergyDifference = ((totalcheck < 0m) ? 0m : totalcheck);
				powerConsumption.MeterId = meterInfo.Id;
				DataHandling(upload, powerConsumption, multiplier);
				if (meterInfo.GateStatus == 0 && powerConsumption.ActivePowerAll > 0m)
				{
					DateTime dateTime = DateTime.Now;
					EarlyWarning earlyWarning = new EarlyWarning
					{
						TenantId = meterInfo.TenantId,
						CreateTime = dateTime,
						Status = 0,
						IsDelete = false,
						WarningId = meterInfo.Id,
						WarningTarget = meterInfo.Sn,
						WarningTargetType = 0,
						WarningType = 2,
						WarningMsg = $"当前设备{meterInfo.Name}设备编号{meterInfo.Sn}，存在异常数据，当前电表状态拉闸，当前用电功率{powerConsumption.ActivePowerAll}"
					};
					await _context.Context.Insertable(earlyWarning).ExecuteCommandAsync();
				}
				if (ruleInfo != null)
				{
					powerConsumption.Price = ruleInfo.Price ?? (-1m);
					powerConsumption.FlatPrice = ruleInfo.FlatPrice ?? (-1m);
					powerConsumption.ValleyPrice = ruleInfo.ValleyPrice ?? (-1m);
					powerConsumption.PeakPrice = ruleInfo.PeakPrice ?? (-1m);
					powerConsumption.SharpPrice = ruleInfo.SharpPrice ?? (-1m);
					powerConsumption.DeepValleyPrice = ruleInfo.DeepValleyPrice ?? (-1m);
					powerConsumption.Type = ruleInfo.Type;
				}
				else
				{
					powerConsumption.Price = -1;
					powerConsumption.FlatPrice = -1;
					powerConsumption.ValleyPrice = -1;
					powerConsumption.PeakPrice = -1;
					powerConsumption.SharpPrice = -1;
					powerConsumption.DeepValleyPrice = -1;
					powerConsumption.Type = -1;
				}
				powerConsumption.Amount = ((allfee < 0m) ? 0m : allfee);
				powerConsumption.Id = YitIdHelper.NextId();
				powerConsumption.IsDelete = false;
				powerConsumption.LossAmount = lossfee;
				WarningRule waring;
				if (roomInfo != null)
				{
					powerConsumption.RoomId = roomInfo.Id;
					powerConsumption.BuildingId = roomInfo.BuildingId;
					decimal can_deduct_fee = allfee;
					updateRoom = from u in _context.Context.Updateable<Room>()
						where u.Id == roomInfo.Id
						select u;
					if (allfee > 0m)
					{
						decimal monery = default(decimal);
						if (meterInfo.IsSubsidy == 1)
						{
							IUpdateable<ElectricMeter> updateMeter = from u in _context.Context.Updateable<ElectricMeter>()
								where u.Id == meterInfo.Id
								select u;
							if (TimeCompareMonth(meterInfo.ReservationSubsidyTime.Value, DateTime.Now) && (!meterInfo.SubsidyTime.HasValue || !TimeCompare(meterInfo.ReservationSubsidyTime.Value, meterInfo.SubsidyTime.Value)))
							{
								meterInfo.NowSubsidyFee = 0m;
								meterInfo.SubsidyTime = meterInfo.ReservationSubsidyTime.Value;
								meterInfo.SubsidyFee = meterInfo.ReservationSubsidyFee;
								updateMeter = updateMeter.SetColumns((ElectricMeter u) => u.NowSubsidyFee == 0m).SetColumns((ElectricMeter u) => u.SubsidyTime == meterInfo.ReservationSubsidyTime.Value).SetColumns((ElectricMeter u) => u.SubsidyFee == meterInfo.ReservationSubsidyFee);
							}
							if (meterInfo.NowSubsidyFee < meterInfo.SubsidyFee)
							{
								decimal subMonery = meterInfo.SubsidyFee - meterInfo.NowSubsidyFee;
								monery = ((subMonery > allfee + lossfee) ? (allfee + lossfee) : subMonery);
							}
							powerConsumption.SubsidyFee = meterInfo.SubsidyFee;
							powerConsumption.NowSubsidyFee = monery;
							await updateMeter.SetColumns((ElectricMeter u) => u.NowSubsidyFee == u.NowSubsidyFee + monery).ExecuteCommandAsync();
						}
						if (allfee + lossfee > monery)
						{
							can_deduct_fee = allfee + lossfee - monery;
						}
					}
					updateRoom = updateRoom.SetColumns((Room u) => u.Balance == u.Balance - can_deduct_fee);
					if (can_deduct_fee != 0m)
					{
						RoomService _roomService = App.GetService<RoomService>();
						string msg = "用电结算";
						if (lossfee > 0m)
						{
							msg += $"(电损{Math.Round(lossfee, 2)}元)";
						}
						await _roomService.AddRoomBalanceRecord(_contextTwo.Context, roomInfo.Id, powerConsumption.Id, 1, -can_deduct_fee, roomInfo.TenantId.Value, msg);
					}
					if (roomInfo.WarningRuleId.HasValue)
					{
						waring = await (from u in _context.Context.Queryable<WarningRule>()
							where (long?)u.Id == roomInfo.WarningRuleId
							select u).FirstAsync();
						if (waring != null)
						{
							if (waring.IsDelete)
							{
							}
							nowBalance = roomInfo.Balance - can_deduct_fee;
							decimal num8 = nowBalance;
							combinedActiveTotalElectricEnergy = waring.FirstThreshold;
							if ((num8 <= combinedActiveTotalElectricEnergy.GetValueOrDefault()) & combinedActiveTotalElectricEnergy.HasValue)
							{
								if (!roomInfo.LatestWarningBalance.HasValue)
								{
									goto IL_362b;
								}
								if (roomInfo.LatestWarningBalance > waring.SecondThreshold)
								{
									decimal num9 = nowBalance;
									decimal? secondThreshold = waring.SecondThreshold;
									if ((num9 < secondThreshold.GetValueOrDefault()) & secondThreshold.HasValue)
									{
										goto IL_362b;
									}
								}
								if (roomInfo.LatestWarningBalance < waring.SecondThreshold && roomInfo.LatestWarningBalance > waring.LastThreshold)
								{
									decimal num10 = nowBalance;
									decimal? secondThreshold = waring.LastThreshold;
									num = (((num10 < secondThreshold.GetValueOrDefault()) & secondThreshold.HasValue) ? 1 : 0);
								}
								else
								{
									num = 0;
								}
								goto IL_362c;
							}
							goto IL_3a05;
						}
					}
					goto IL_3b32;
				}
				goto IL_3c92;
				IL_362b:
				num = 1;
				goto IL_362c;
				IL_3ab1:
				int num11;
				if (num11 != 0)
				{
					isSwitch = true;
				}
				goto IL_3b32;
				IL_3b32:
				await updateRoom.ExecuteCommandAsync();
				goto IL_3c92;
				IL_3a05:
				if (waring.AllowOverdrawLimit.HasValue && nowBalance <= 0m)
				{
					decimal value2 = nowBalance;
					combinedActiveTotalElectricEnergy = waring.AllowOverdrawLimit;
					decimal? secondThreshold = (decimal?)value2 + combinedActiveTotalElectricEnergy;
					if ((secondThreshold.GetValueOrDefault() <= default(decimal)) & secondThreshold.HasValue)
					{
						num11 = ((upload.State == "0000") ? 1 : 0);
						goto IL_3ab1;
					}
				}
				num11 = 0;
				goto IL_3ab1;
				IL_3c92:
				if (powerConsumption != null)
				{
					powerConsumption.IsDelete = false;
					if (!powerConsumption.ElectricityLossPercentage.HasValue)
					{
						powerConsumption.ElectricityLossPercentage = 0.0;
					}
					await _contextTwo.InsertAsync(powerConsumption);
				}
				await _context.Context.Ado.CommitTranAsync();
				await _contextTwo.Context.Ado.CommitTranAsync();
				goto end_IL_016c;
			}
			catch (Exception)
			{
				await _context.Context.Ado.RollbackTranAsync();
				await _contextTwo.Context.Ado.RollbackTranAsync();
				goto end_IL_016c;
			}
			end_IL_016c:;
		}
		finally
		{
			_context.Context.Dispose();
			_contextTwo.Context.Dispose();
			if (isSwitch)
			{
				try
				{
					ElectricityService service = App.GetService<ElectricityService>();
					InputSwitch item = new InputSwitch
					{
						Id = meterInfo.Id,
						GateStatus = 1
					};
					await service.SwitchMeter(item, meterInfo.TenantId);
				}
				catch (Exception)
				{
				}
			}
		}
	}

	/// <summary>
	/// 数据处理
	/// </summary>
	/// <param name=" upload"></param>
	/// <param name="powerConsumption"></param>
	private void DataHandling(UploadMqttInfo upload, PowerConsumptionRecord powerConsumption, decimal multiplier)
	{
		if (!string.IsNullOrEmpty(upload.ActivePowerAll))
		{
			string[] acticePower = upload.ActivePowerAll.Split(',');
			if (acticePower.Length == 4)
			{
				powerConsumption.ActivePowerAll = ChangeDataToD(acticePower[3]) * multiplier;
				powerConsumption.ActivePowerA = ChangeDataToD(acticePower[2]) * multiplier;
				powerConsumption.ActivePowerB = ChangeDataToD(acticePower[1]) * multiplier;
				powerConsumption.ActivePowerC = ChangeDataToD(acticePower[0]) * multiplier;
			}
			else if (!string.IsNullOrEmpty(upload.Pa))
			{
				powerConsumption.ActivePowerAll = ChangeDataToD(upload.Pa) * multiplier;
				powerConsumption.ActivePowerA = ChangeDataToD(upload.Pa) * multiplier;
			}
		}
		if (!string.IsNullOrEmpty(upload.CurrentAll))
		{
			string[] current = upload.CurrentAll.Split(',');
			if (current.Length == 3)
			{
				powerConsumption.CurrentA = ChangeDataToD(current[2]) * multiplier;
				powerConsumption.CurrentB = ChangeDataToD(current[1]) * multiplier;
				powerConsumption.CurrentC = ChangeDataToD(current[0]) * multiplier;
			}
			else if (!string.IsNullOrEmpty(upload.Ia))
			{
				powerConsumption.CurrentA = ChangeDataToD(upload.Ia) * multiplier;
			}
		}
		if (!string.IsNullOrEmpty(upload.VoltageAll))
		{
			string[] voltage = upload.VoltageAll.Split(',');
			if (voltage.Length == 3)
			{
				powerConsumption.VoltageA = ChangeDataToD(voltage[2]);
				powerConsumption.VoltageB = ChangeDataToD(voltage[1]);
				powerConsumption.VoltageC = ChangeDataToD(voltage[0]);
			}
			else if (!string.IsNullOrEmpty(upload.Ua))
			{
				powerConsumption.VoltageA = ChangeDataToD(upload.Ua) * multiplier;
			}
		}
		if (upload.ActivePowerAll == null && upload.VoltageAll == null && upload.CurrentAll == null)
		{
			powerConsumption.IsHands = true;
		}
	}

	private bool TimeCompareMonth(DateTime? tOne, DateTime tTwo)
	{
		if (!tOne.HasValue)
		{
			return false;
		}
		return tOne?.Year == tTwo.Year && tOne?.Month == tTwo.Month;
	}

	private bool TimeCompare(DateTime tOne, DateTime tTwo)
	{
		return (tOne - tTwo).TotalSeconds == 0.0;
	}

	private decimal ChangeDataToD(string strData)
	{
		decimal dData = default(decimal);
		if (strData.ToLower().Contains("e"))
		{
			decimal d = decimal.Parse(strData, NumberStyles.Float);
			CultureInfo cultureInfo = new CultureInfo("cn");
			decimal.TryParse(strData, NumberStyles.Float, cultureInfo, out dData);
		}
		else
		{
			decimal.TryParse(strData, out dData);
		}
		return dData;
	}

	private async Task FreezeInfoHandle(SqlSugarRepository<ElectricMeter> _rep, ElectricMeter meter, string datetime, string all)
	{
		if (string.IsNullOrEmpty(datetime) || datetime == "0000000000")
		{
			return;
		}
		string format = "yyyyMMddHHmm";
		if (!DateTime.TryParse(provider: new DateTimeFormatInfo
		{
			ShortDatePattern = format
		}, s: "20" + datetime, styles: DateTimeStyles.None, result: out var dateTime))
		{
			return;
		}
		List<ElectricMeterFreeze> model = (from u in _rep.Context.Queryable<ElectricMeterFreeze>()
			where u.Sn == meter.Sn && u.ElectricMeterFreezeTime == dateTime
			select u).ToList();
		if (model.Count <= 0)
		{
			string[] valuearr = all.Split(",");
			if (valuearr.Length == 1)
			{
				valuearr = new string[6]
				{
					"0",
					"0",
					"0",
					"0",
					"0",
					valuearr[0]
				};
			}
			if (valuearr.Length == 5)
			{
				valuearr = new string[6]
				{
					"0",
					valuearr[0],
					valuearr[1],
					valuearr[2],
					valuearr[3],
					valuearr[4]
				};
			}
			ElectricMeterFreeze electricMeterInfo = new ElectricMeterFreeze
			{
				Sn = meter.Sn,
				MeterId = meter.Id,
				Addr = meter.Addr,
				LowAddr = meter.LowAddr,
				CombinedActiveDeepValleyElectricEnergy = ChangeDataToD(valuearr[0]) * (decimal)meter.Multiplier,
				CombinedActiveValleyElectricEnergy = ChangeDataToD(valuearr[1]) * (decimal)meter.Multiplier,
				CombinedActiveFlatElectricEnergy = ChangeDataToD(valuearr[2]) * (decimal)meter.Multiplier,
				CombinedActivePeakElectricEnergy = ChangeDataToD(valuearr[3]) * (decimal)meter.Multiplier,
				CombinedActiveSharpElectricEnergy = ChangeDataToD(valuearr[4]) * (decimal)meter.Multiplier,
				CombinedActiveTotalElectricEnergy = ChangeDataToD(valuearr[5]) * (decimal)meter.Multiplier
			};
			await _rep.Context.Insertable(electricMeterInfo).ExecuteCommandAsync();
		}
	}
}
